#ifndef __57ACCTABC_H__
#define __57ACCTABC_H__

#include <iostream>
#include <string>

// AcctABC Class
class AcctABC
{
private:
    std::string fullName;
    long acctNum;
    double balance;

protected:
// 定义了一个结构用于存储输出的配置;并且使用来设置和恢复格式
// 只需要使用setFormat()和Restore()函数即可设定cout对象的输出样式
    struct Formatting
    {
        std::ios_base::fmtflags flag;
        std::streamsize pr;
    };
    const std::string &FullName() const { return fullName; }
    long AcctNum() const { return acctNum; }
    Formatting SetFormat() const;
    void RestoreFormatting(Formatting &f) const;

public:
    void Deposit(double amt = 0);
    virtual void WithDraw(double amt) = 0; // pure virtual function
    double Balance() const { return balance; }
    virtual void ViewAcct() const = 0; // pure virtual function

    // AcctABC(const std::string &s = "Nullbody", long an = -1, double bal = 0.0) : fullname(s), acctNum(an), balance(bal) {}
    AcctABC(const std::string &s = "Nullbody", long an = -1, double bal = 0.0);
    virtual ~AcctABC() {}
};

// Brass Class
class Brass : public AcctABC
{
public:
    Brass(const std::string &s = "Nullbody", long an = -1, double bal = 0.0) : AcctABC(s, an, bal) {}
    virtual void WithDraw(double amt);
    virtual void ViewAcct() const;

    virtual ~Brass() {}
};

// 一不小心好像会了多继承
// class BrassPlus : public AcctABC,Brass
class BrassPlus : public AcctABC
{
private:
    // BrassPlus继承于Brass继承于AcctABC
    double maxLoan;
    double rate;
    double owesBank;

public:
    BrassPlus(const std::string &s = "Nullbody", long an = -1, double bal = 0.0, double ml = 500, double r = 0.10);
    BrassPlus(const Brass &ba, double ml = 500, double r = 0.1);
    virtual void ViewAcct() const;
    virtual void WithDraw(double amt);

    void ResetMaxLoan(double m) { maxLoan = m; }
    void ResetRate(double r) { rate = r; }
    void ResetOwesBank() { owesBank = 0; }

    virtual ~BrassPlus() {}
};

#endif // __57ACCTABC_H__